package com.bolt.support.base.service;

import com.bolt.convention.data.PageInfo;
import com.bolt.support.spring.jpa.filter.GroupPropertyFilter;
import com.bolt.support.spring.jpa.filter.IFilterBuilder;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.Nullable;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

/**
 * Created by Administrator on 2021/4/14.
 */
public interface IBaseService<T,ID> {
    /**
     * 数据保存操作
     *
     * @param entity
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    T save(T entity);

    /**
     * 批量数据保存操作 其实现只是简单循环集合每个元素调用
     * 因此并无实际的Batch批量处理，如果需要数据库底层批量支持请自行实现
     *
     * @param entities 待批量操作数据集合
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    List<T> save(Iterable <T> entities);

    /**
     * 批量插入数据
     *
     * @param entities
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    List <T> batchInsert(List <T> entities, int batchSize);

    /**
     * 批量修改数据
     *
     * @param entities
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    List <T> batchUpdate(List <T> entities, int batchSize);

    /**
     * 基于主键查询单一数据对象
     *
     * @param id
     * @return
     */
    Optional<T> findOne(ID id);

    /**
     * 基于动态组合条件对象和排序定义查询数据集合
     *
     * @param filter
     * @return
     */
    @Deprecated
    Optional <T> findOne(GroupPropertyFilter filter);

    Optional <T> findOne(IFilterBuilder<T> builder);

    List <T> findAll(GroupPropertyFilter filter);

    List <T> findAll(IFilterBuilder <T> builder);
    /**
     * 基于主键集合查询集合数据对象
     *
     * @param ids 主键集合
     * @return
     */
    @SuppressWarnings("unchecked")
    List <T> findAll(Iterable <ID> ids);

    /**
     * 基于主键集合查询集合数据对象
     *
     * @param ids 主键集合
     * @return
     */
    List <T> findAll(ID... ids);

    /**
     * 查询全部数据对象
     *
     * @return
     */
    @SuppressWarnings("unchecked")
    List <T> findAll();

    List <T> findAll(@Nullable Specification<T> spec,Sort sort);

    List <T> findLimit(@Nullable Specification<T> spec, Sort sort, int limit);

    List <T> findLimit(IFilterBuilder <T> builder, Sort sort, int limit);

    List <T> findLimit(GroupPropertyFilter filter, Sort sort, int limit);



    /**
     * 数据删除操作
     *
     * @param entity 待操作数据
     */

    @Transactional(rollbackFor = Exception.class)
    void delete(T entity);

    /**
     * 批量数据删除操作 其实现只是简单循环集合每个元素调用
     * 因此并无实际的Batch批量处理，如果需要数据库底层批量支持请自行实现
     *
     * @param entities 待批量操作数据集合
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    void delete(Iterable <T> entities);

    @Transactional(rollbackFor = Exception.class)
    void deleteById(ID id);

    PageInfo<T> findPage(Pageable pageable, GroupPropertyFilter filters);

    PageInfo <T> findPage(Pageable pageable, @Nullable Specification <T> spec);

    PageInfo <T> findPage(Pageable pageable, IFilterBuilder <T> builder);

    /**
     * 查询符合条件的行数
     *
     * @param filters
     * @return
     */
    @SuppressWarnings("unchecked")
    long findCount(GroupPropertyFilter filters);

    long findCount(IFilterBuilder <T> builder);

    long findCount( @Nullable Specification <T> spec);
    /**
     * 更新过滤不更新属性
     *
     * @param entity
     * @param ignoreProperties
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    T update(T entity, String... ignoreProperties);

    /**
     * 可以做为VO向PO转存的简单实现方法
     *
     * @param vo               游离对象或前端转来的VO
     * @param entity           PO实体
     * @param ignoreProperties 忽略处理的属性名称
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    T update(Object vo, T entity, String... ignoreProperties);



    void detach(Object entity);
}
